﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.SharePoint;
using TSOL.FastSPWeb.ValueObjects;
using TSOL.FastSPWeb.Core;

namespace TSOL.FastSPWeb
{
    public static partial class FastSPWebCallExtensions
    {
        public enum CachePolicy {NoCache, FastSPDefault }

        public static void FastItems(this SPList List, CachePolicy cachePolicy, Action<SPListItemCollection> outProc)
        {
            Guid SiteGuid = List.ParentWeb.Site.ID;
            Guid WebGuid = List.ParentWeb.ID;
            SPUser CurrentSPUser = List.ParentWeb.CurrentUser;

            var hashKey = (SiteGuid.ToString() + WebGuid.ToString() + List.ID.ToString() + true.ToString() + CurrentSPUser.ID.ToString()).GetHashCode();

            SPItemsCacheCollection _SPItemsCacheCollection = null;
            SPItemsCacheEntity _ItemsCache = null;

            while (_ItemsCache == null)
            {
                while (!FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.ItemsCacheDictionary.TryGetValue(hashKey, out _SPItemsCacheCollection))
                {
                    _SPItemsCacheCollection = new SPItemsCacheCollection()
                    {
                        UserUniqueID = CurrentSPUser.ID.ToString(),
                        SiteGuid = SiteGuid,
                        WebGuid = WebGuid,
                        ListGuid = List.ID,
                        MaxCopiesOfElevatedItems = List.ParentWeb.Site.SystemAccount.UserToken.CompareUser(CurrentSPUser.UserToken) ?
                                            FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.MaxCopiesOfElevatedItems :
                                            -1
                    };
                    FastSPItemsFactoryThread.FastSPItemsFactoryThreadTask(List, CurrentSPUser.UserToken, hashKey, _SPItemsCacheCollection);
                }

                if (_SPItemsCacheCollection.Count() == 0) FastSPItemsFactoryThread.FastSPItemsFactoryThreadTask(List, CurrentSPUser.UserToken, hashKey, _SPItemsCacheCollection);

                _ItemsCache = _SPItemsCacheCollection.FirstOrDefault(a => a.Free == true);
                if (_ItemsCache != default(SPItemsCacheEntity))
                    break;
                else
                {
                    lock (_SPItemsCacheCollection) _SPItemsCacheCollection.WaitingForFreeItems++;
                    FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.FastSPItemsWaitingForFreeCacheEntity++;
                }
            }
            lock (_ItemsCache)
            {
                _ItemsCache.Free = false;
                outProc(_ItemsCache.Items);
                _ItemsCache.LastUsed = DateTime.Now;
                _ItemsCache.Free = true;
            }
        }
    }
}